/******************************************************************************
	@Author: Manh Cuong
  @CreatDate: 29/06/2012
	@Application: uart platform
*******************************************************************************/

#include "plat_uart.h"
#include "typedef.h"

const uint16_t IOCOMRxPin[5] ={
		COM1RxPIN,
	  COM2RxPIN,
	  COM3RxPIN,
	  COM4RxPIN,
	  COM5RxPIN
};
const uint16_t IOCOMTxPin[5] ={
		COM1TxPIN,
	  COM2TxPIN,
	  COM3TxPIN,
	  COM4TxPIN,
	  COM5TxPIN
};
GPIO_TypeDef* IOCOMRxPort[5]={
    COM1RxPORT,
	  COM2RxPORT,
	  COM3RxPORT,
	  COM4RxPORT,
	  COM5RxPORT
};
GPIO_TypeDef* IOCOMTxPort[5]={
    COM1TxPORT,
	  COM2TxPORT,
	  COM3TxPORT,
	  COM4TxPORT,
	  COM5TxPORT
};
const uint32_t RCCCOMRxPort[5] = {
	  COM1RxCLK,
	  COM2RxCLK,
	  COM3RxCLK,
	  COM4RxCLK,
	  COM5RxCLK,
};
const uint32_t RCCCOMTxPort[5] = {
	  COM1TxCLK,
	  COM2TxCLK,
	  COM3TxCLK,
	  COM4TxCLK,
	  COM5TxCLK,
};

USART_TypeDef * COMName[5]={
	COM1,
	COM2,
	COM3,
	COM4,
	COM5
};

const ULONG COMBaud[6] = {
	4800,
	9600,
	19200,
	38400,
	57600,
	115200
};

const uint32_t COMCLK [5] = {
	COM1CLK,
	COM2CLK,
	COM3CLK,
	COM4CLK,
	COM5CLK
};

const IRQn_Type sIRQ_Channel[5] = {
	COM1IRQChannel,
	COM2IRQChannel,
	COM3IRQChannel,
	COM4IRQChannel,
	COM5IRQChannel
	
};
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
 
int fputc(int ch, FILE *f)
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(CONSOLE, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(CONSOLE, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

/**
  @brief COM Init
  @param: 
       eSerCOM:
						 eSerCOM1,
						 eSerCOM2,
						 eSerCOM3,
						 eSerCOM4,
						 eSerCOM5,
       eBaudrate: 
              sbaud_4800,
							sbaud_9600,
							sbaud_19200,
							sbaud_38400,
							sbaud_57600,
							sbaud_115200
   @retval: None
*/
void COMInit(
          serCOM COM,
					eBaudrate uWantBaud
){                    /*UART init                     */
   USART_InitTypeDef USART_InitStructure;
   GPIO_InitTypeDef GPIO_InitStructure;
	 if(COM>eSerCOM5)    //invalid COM port
		  return;
	 /** Enable USART clock */
	 if(COM>eSerCOM1)
		 RCC_APB1PeriphClockCmd(RCCCOMRxPort[COM]|RCCCOMTxPort[COM]|COMCLK[COM], ENABLE );	
	 else
		 RCC_APB2PeriphClockCmd(RCCCOMRxPort[COM]|RCCCOMTxPort[COM]|COMCLK[COM], ENABLE );	
		/* Configure USART Rx  as input floating */
		GPIO_InitStructure.GPIO_Pin = IOCOMRxPin[COM];
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
		GPIO_Init( IOCOMRxPort[COM], &GPIO_InitStructure );
		/* Configure USART Tx  as alternate function push-pull */
		GPIO_InitStructure.GPIO_Pin = IOCOMTxPin[COM];
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
		GPIO_Init( IOCOMTxPort[COM], &GPIO_InitStructure );
	 
	  USART_InitStructure.USART_BaudRate = COMBaud[uWantBaud];
		USART_InitStructure.USART_WordLength = USART_WordLength_8b;
		USART_InitStructure.USART_StopBits = USART_StopBits_1;
		USART_InitStructure.USART_Parity = USART_Parity_No ;
		USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
		USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	  
	  USART_Init( COMName[COM], &USART_InitStructure );
		USART_Cmd( COMName[COM], ENABLE );	
		putchar(0x00);
}
/**
  @brief COM interrupt enable, disable
  @param:
          serCOM: see more in header file
          FunctionalState: 
                  ENABLE or DISABLE
  @retval: None
*/
void COMInterrupt(serCOM sWant,FunctionalState s){            /*UART interrupt enable/disable */
	NVIC_InitTypeDef NVIC_InitStructure;
	USART_ITConfig( COMName[sWant], USART_IT_RXNE, s );
	NVIC_InitStructure.NVIC_IRQChannel = sIRQ_Channel[sWant];
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = sWant;
	NVIC_InitStructure.NVIC_IRQChannelCmd = s;
  NVIC_Init( &NVIC_InitStructure );
}


/**
   * @brief  Put Data to USARTx 
   * @param  
   		- USART_TypeDef* USARTx : UART Channel
		- int ch : data sent to UART
   * @retval None
   */ 
int UART_putc(USART_TypeDef * USARTx,int ch)
{
  USART_SendData(USARTx, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

/**
   * @brief  Put string to USARTx 
   * @param  
   		- USART_TypeDef* USARTx : UART Channel
		- char string[] : string sent to UART
   * @retval None
   */ 
int UART_printf(USART_TypeDef * USARTx,char * string)
{
	int i = 0;
	while(string[i]!=0)
 		{UART_putc(USARTx,string[i]);i++;}
	return 0;
}
